home *** CD-ROM | disk | FTP | other *** search
/ Night Owl 6 / Night Owl's Shareware - PDSI-006 - Night Owl Corp (1990).iso / 039a / soundhax.zip / REC_CD.C < prev    next >
C/C++ Source or Header  |  1991-12-19  |  8KB  |  376 lines

  1. /*-------------------------------------------------------*/
  2. /* Originally part of SOUNDHAX v1 by John M. Trindle     */
  3. /*                 FREEWARE 12/19/91                     */
  4. /*-------------------------------------------------------*/
  5.  
  6. #include <stdio.h>
  7. #include <stdlib.h>
  8. #include <dos.h>
  9. #include <string.h>
  10.  
  11. #define MULTIPLEX_INT   0x2f
  12. #define INIT_MP_INT     0x1500;
  13. #define CDREQ_MP_INT    0x1510;
  14.  
  15. #define STAT_HAS_AN_ERROR 0x8000
  16. #define STAT_BUSY         0x0200
  17. #define STAT_DONE         0x0100
  18.  
  19. int CDRomLoaded,CDRomDrive;
  20.  
  21. #define CD_EJECT_COMMAND      0
  22. #define CD_SEEK_COMMAND       131
  23. #define CD_PLAY_COMMAND       132
  24. #define CD_STOP_COMMAND       133
  25. #define CD_RESUME_COMMAND     136
  26.  
  27. #define READ_IOCTL_COMMAND   3
  28. #define WRITE_IOCTL_COMMAND  12
  29.  
  30. #define CD_STATUS_COMMAND     6
  31.  
  32. #define GET_AUDIO_DISKINFO    10
  33. #define GET_AUDIO_TRACKINFO   11
  34.  
  35.  
  36. #define        ADDR_HSG        0
  37. #define        ADDR_RED        1
  38.  
  39. #define  CMS_AVAILABLE  1
  40. #define  FM_AVAILABLE   2
  41. #define  CV_AVAILABLE   4
  42.  
  43. #define  OFF            0
  44. #define  ON             1
  45.  
  46. #define  FALSE          0
  47. #define  TRUE           1
  48.  
  49. extern _ct_io_addx;
  50. extern _ct_int_num;
  51. extern _ct_music_status;
  52. extern _ct_voice_status;
  53.  
  54. static int StatusWord;
  55.  
  56. typedef struct
  57. {
  58.    unsigned char ParamLength;
  59.    unsigned char SubUnit;
  60.    unsigned char CommandCode;
  61.    int           Status;
  62.    unsigned long Reserved1;
  63.    unsigned long Reserved2;
  64.    unsigned char AddressMode;
  65.    void     *BeginPointer;
  66.    unsigned long Length;
  67.    unsigned long Reserved3;
  68. } CDCmdStru;
  69.  
  70. typedef struct
  71. {
  72.    unsigned char CommandCode;
  73.    unsigned char TrackNumber;
  74.    unsigned long StartAddress;
  75.    unsigned char Control;
  76. } CDTrackInfoStru;
  77.  
  78. typedef struct
  79. {
  80.   unsigned char CommandCode;
  81. } CDEjectStru;
  82.  
  83. typedef struct
  84. {
  85.   unsigned char CommandCode;
  86.   unsigned long Status;
  87. } CDStatusStru;
  88.  
  89. typedef struct
  90. {
  91.    unsigned char AddrMode;
  92.    unsigned long FrameOffset;
  93.    unsigned long NumberFrames;
  94. } CDPlayStru;
  95.  
  96. typedef struct DiskInfo_Rec {
  97.    unsigned char CommandCode;
  98.    unsigned char LoTrack;
  99.    unsigned char HiTrack;
  100.    unsigned long LeadOut;
  101. } CDDiskInfoStru;
  102.  
  103.  
  104. CDCmdStru CDCmdBlock;
  105. CDTrackInfoStru TrackInfo[100];
  106. CDDiskInfoStru DiskInfo;
  107.  
  108. SendCDCommand(int CommandCode, void *BeginPtr, long Length);
  109. unsigned long CDTrackInfo(int TrackNumber, int Minutes,
  110.                           int Seconds, int Frames);
  111. CDPlay(long Offset,long NumFrames);
  112. unsigned int CDStatus();
  113. PrintTimeFrames(long NumFrames);
  114. unsigned long Red2HSG(unsigned long RedValue);
  115.  
  116. long LastSector;
  117. int NumTracks;
  118.  
  119. main(int argc, char *argv[])
  120. {
  121.    int i,j,DriverFeatures=0;
  122.  
  123.    int Track,StartMin,StartSec,EndMin,EndSec,StartFrame,EndFrame;
  124.    long StartSector,EndSector;
  125.  
  126.    FILE *outfp;
  127.  
  128.    float TempFloat;
  129.    char LocalBuffer[132];
  130.  
  131.    if (!CheckCD2F())
  132.    {
  133.       printf("MSCDEX NOT LOADED\n");
  134.       exit(1);
  135.    }
  136.  
  137.    CDGetDiskInfo();
  138.    LastSector = DiskInfo.LeadOut;
  139.    NumTracks = DiskInfo.HiTrack-DiskInfo.LoTrack+1;
  140.  
  141.    printf("Reading Drive %c\n",CDRomDrive+'A');
  142.  
  143.    if (argc > 1)
  144.    {
  145.       Track = atoi(argv[1]);
  146.       printf("Starting Track %d, %d tracks on disk\n",Track,NumTracks);
  147.    }
  148.    else
  149.    {
  150.       for (i = DiskInfo.LoTrack; i <= DiskInfo.HiTrack; i++)
  151.       {
  152.          CDTrackInfo(i,0,0,0);
  153.       }
  154.  
  155.       TrackInfo[DiskInfo.HiTrack+1].StartAddress = DiskInfo.LeadOut;
  156.  
  157.       for (i = DiskInfo.LoTrack; i <= DiskInfo.HiTrack; i++)
  158.       {
  159.          printf("Track %2d ",i);
  160.          PrintTimeFrames(Red2HSG(TrackInfo[i+1].StartAddress)-Red2HSG(TrackInfo[i].StartAddress));
  161.          printf("\n");
  162.       }
  163.    }
  164.  
  165.    if (argc < 2)
  166.    {
  167.       exit(0);
  168.    }
  169.  
  170.    outfp = NULL;
  171.  
  172.    EndSector = Red2HSG(DiskInfo.LeadOut)-150L;  /* 150L Fudge Factor */
  173.  
  174.    StartMin = 0;
  175.    StartSec = 0;
  176.    StartFrame = 0;
  177.  
  178.    EndMin = 0;
  179.    EndSec = 0;
  180.    EndFrame = 0;
  181.  
  182.    if (argc > 2)
  183.    {
  184.       strcpy(LocalBuffer,argv[2]);
  185.  
  186.       StartMin = atoi(strtok(LocalBuffer,":"));
  187.       TempFloat = atof(strtok(NULL,":"));
  188.  
  189.       StartSec = (int) TempFloat;
  190.       StartFrame = ((int)(TempFloat*75))-StartSec*75;
  191.    } 
  192.    StartSector = CDTrackInfo(Track,StartMin,StartSec,StartFrame);
  193.  
  194.    if (argc > 3)
  195.    {
  196.       strcpy(LocalBuffer,argv[3]);
  197.  
  198.       EndMin = atoi(strtok(LocalBuffer,":"));
  199.       TempFloat = atof(strtok(NULL,":"));
  200.  
  201.       EndSec = (int) TempFloat;
  202.       EndFrame = ((int)(TempFloat*75))-EndSec*75;
  203.  
  204.       EndSector   = CDTrackInfo(Track,EndMin,EndSec,EndFrame);
  205.    } 
  206.  
  207.    CDStop();
  208.  
  209.    if (argc > 4)
  210.    {
  211.       _ct_io_addx = 0x220;    /* I/O Base */
  212.       DriverFeatures = _ct_card_here();
  213.       if (DriverFeatures & CV_AVAILABLE)
  214.       {
  215.          _sbc_scan_int();
  216.          _ctvd_init(6);
  217.  
  218.          printf("opening file %s\n",argv[4]);
  219.          outfp = fopen(argv[4],"wb");
  220.  
  221.          _ctvd_speaker(OFF);
  222.          _ctvd_input(outfp->_file,250);
  223.       }
  224.  
  225.    }
  226.  
  227.    CDPlay(StartSector,EndSector-StartSector);
  228.  
  229.    if (outfp != NULL)
  230.    {
  231.       printf("Press any key to abort\n");
  232.  
  233.       /* This could be keyed on CDStatus BUSY, but corrupts sample */
  234.  
  235.       while(TRUE)
  236.       {
  237.          if (kbhit())
  238.          {
  239.             getch();
  240.             CDStop();
  241.             break;
  242.          }
  243.       }
  244.    } 
  245.  
  246.    printf("\n");
  247.  
  248.    if (outfp != NULL)
  249.       fclose(outfp);
  250.  
  251.    if (DriverFeatures & CV_AVAILABLE && argc > 4)
  252.       _ctvd_terminate();
  253.    
  254. }
  255.  
  256.  
  257. CheckCD2F()
  258. {
  259.    union REGS regs;
  260.  
  261.    regs.x.ax = INIT_MP_INT;
  262.    int86(MULTIPLEX_INT,®s,®s);
  263.    CDRomLoaded = regs.x.bx;
  264.    CDRomDrive = regs.x.cx;
  265. }
  266.  
  267. CDEject()
  268. {
  269.    CDEjectStru EjectRequestBlock;
  270.  
  271.    EjectRequestBlock.CommandCode = CD_EJECT_COMMAND;
  272.  
  273.    SendCDCommand(WRITE_IOCTL_COMMAND,&EjectRequestBlock,sizeof(CDEjectStru));
  274. }
  275.  
  276. unsigned int CDStatus()
  277. {
  278.    unsigned int RetVal;
  279.    CDStatusStru StatusRequestBlock;
  280.  
  281.    StatusRequestBlock.CommandCode = CD_STATUS_COMMAND;
  282.  
  283.    RetVal = SendCDCommand(READ_IOCTL_COMMAND,&StatusRequestBlock,sizeof(CDStatusStru));
  284.    return(RetVal);
  285. }
  286.  
  287. CDStop()
  288. {
  289.    return(SendCDCommand(CD_STOP_COMMAND,NULL,0));
  290. }
  291.  
  292.  
  293. CDResume()
  294. {
  295.    return(SendCDCommand(CD_RESUME_COMMAND,NULL,0));
  296. }
  297.  
  298. CDPlay(long FrameOffset, long NumFrames)
  299. {
  300.    SendCDCommand(CD_PLAY_COMMAND,(void *)FrameOffset,NumFrames);
  301. }
  302.  
  303. CDGetDiskInfo()
  304. {
  305.    DiskInfo.CommandCode = GET_AUDIO_DISKINFO;
  306.    SendCDCommand(READ_IOCTL_COMMAND,&DiskInfo,sizeof(CDDiskInfoStru));
  307. }
  308.  
  309. PrintTimeFrames(long NumFrames)
  310. {
  311.    long Mins;
  312.    long Secs;
  313.    long PlusFrames;
  314.    PlusFrames = NumFrames;
  315.    Secs = PlusFrames/75;
  316.    PlusFrames -= Secs*75;
  317.    Mins = Secs/60;
  318.    Secs -= Mins*60;
  319.  
  320.    printf("%2ld:%02ld:%02ld",Mins,Secs,PlusFrames);
  321. }
  322.  
  323. SendCDCommand(int CommandCode, void *BeginPtr, long Length)
  324. {
  325.    union REGS regs;
  326.    struct SREGS sregs;
  327.  
  328.    CDCmdBlock.ParamLength = 13;
  329.    CDCmdBlock.SubUnit     = 0;
  330.    CDCmdBlock.CommandCode = CommandCode;
  331.    CDCmdBlock.Status      = 0;
  332.    CDCmdBlock.AddressMode = ADDR_HSG;
  333.    CDCmdBlock.BeginPointer = BeginPtr;
  334.    CDCmdBlock.Length      = Length;
  335.    CDCmdBlock.Reserved3   = 0;
  336.  
  337.    regs.x.ax = CDREQ_MP_INT;
  338.    regs.x.bx = FP_OFF(&CDCmdBlock);
  339.    regs.x.cx = CDRomDrive;
  340.    sregs.es  = FP_SEG(&CDCmdBlock);
  341.  
  342.    int86x(MULTIPLEX_INT,®s,®s,&sregs);
  343.  
  344.    return(CDCmdBlock.Status);
  345. }
  346.  
  347. unsigned long CDTrackInfo(int TrackNumber, int Minutes, int Seconds, int Frames)
  348. {
  349.  
  350.    TrackInfo[TrackNumber].CommandCode = GET_AUDIO_TRACKINFO;
  351.  
  352.    TrackInfo[TrackNumber].TrackNumber = TrackNumber;
  353.  
  354.    SendCDCommand(READ_IOCTL_COMMAND,&(TrackInfo[TrackNumber]),sizeof(CDTrackInfoStru));
  355.  
  356.    return(Red2HSG(TrackInfo[TrackNumber].StartAddress)+(Minutes*60L+((long)Seconds))*75L+((long)Frames));
  357. }
  358.  
  359. unsigned long Red2HSG(unsigned long RedValue)
  360. {
  361.  
  362.    unsigned long Mins;
  363.    unsigned long Secs;
  364.    unsigned long PlusFrames;
  365.  
  366.    PlusFrames = RedValue & 0x000000ffL;
  367.  
  368.    Secs = ((RedValue & 0x0000ff00L) >> 8);
  369.  
  370.    Mins = ((RedValue & 0x00ff0000L) >> 16);
  371.  
  372.    return((Mins*60+Secs)*75+PlusFrames);
  373. }
  374.  
  375.  
  376.